#ifndef BASETEXTFIND_H
#define BASETEXTFIND_H

#include <QObject>
#include <QPointer>
#include <QPlainTextEdit>

enum FindFlag
{
    FindBackward = 0x01,
    FindCaseSensitively = 0x02,
    FindWholeWords = 0x04,
    FindRegularExpression = 0x08,
    FindPreserveCase = 0x10
};

Q_DECLARE_FLAGS(FindFlags, FindFlag)

class WrapIndicator : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity USER true)
public:
    WrapIndicator(QWidget *parent = 0);


    qreal opacity()const;
    void setOpacity(qreal value);

    void run();
protected:
    void paintEvent(QPaintEvent *);
    void runInternal();
private:
    qreal m_opacity;
};


class BaseTextFind : public QObject
{
    Q_OBJECT
public:
    explicit BaseTextFind(QPlainTextEdit *editor);

    enum Result { Found, NotFound, NotYetFound };

    bool supportsReplace() const;
    FindFlags supportedFindFlags() const;
    void resetIncrementalSearch();
    void clearResults();
    QString currentFindString() const;
    QString completedFindString() const;

    Result findIncremental(const QString &txt, FindFlags findFlags);
    Result findStep(const QString &txt, FindFlags findFlags);
    void replace(const QString &before, const QString &after,
        FindFlags findFlags);
    bool replaceStep(const QString &before, const QString &after,
        FindFlags findFlags);
    int replaceAll(const QString &before, const QString &after,
        FindFlags findFlags);

    void defineFindScope();
    void clearFindScope();

signals:
    void highlightAll(const QString &txt, FindFlags findFlags);
    void findScopeChanged(const QTextCursor &start, const QTextCursor &end,
                          int verticalBlockSelectionFirstColumn,
                          int verticalBlockSelectionLastColumn);

private:
    bool find(const QString &txt,
              FindFlags findFlags,
              QTextCursor start,
              bool *wrapped);
    QTextCursor replaceInternal(const QString &before, const QString &after,
                                FindFlags findFlags);

    QTextCursor textCursor() const;
    void setTextCursor(const QTextCursor&);
    QTextDocument *document() const;
    bool isReadOnly() const;
    bool inScope(int startPosition, int endPosition) const;
    QTextCursor findOne(const QRegExp &expr, const QTextCursor &from, QTextDocument::FindFlags options) const;
public:
    static void showWrapIndicator(QWidget *parent);

signals:
    void changed();
signals:
    
public slots:
protected:
    QPointer<QPlainTextEdit> m_plaineditor;
    QPointer<QWidget> m_widget;
    QTextCursor m_findScopeStart;
    QTextCursor m_findScopeEnd;
    int m_findScopeVerticalBlockSelectionFirstColumn;
    int m_findScopeVerticalBlockSelectionLastColumn;
    int m_incrementalStartPos;
    bool m_incrementalWrappedState;
};

#endif // BASETEXTFIND_H
